/*!
 * \file HftMocker.h
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief HFT模拟器头文件
 * 
 * \details 本文件定义了HFT（高频交易）模拟器HftMocker类，用于回测环境下模拟HFT策略的执行。
 *          提供完整的HFT策略上下文接口实现，支持订单管理、持仓管理、Level2数据处理、
 *          高频交易信号处理等功能，为HFT策略回测提供完整的运行环境
 */
#pragma once
#include <queue>
#include <sstream>

#include "HisDataReplayer.h"

#include "../Includes/FasterDefs.h"
#include "../Includes/IHftStraCtx.h"
#include "../Includes/HftStrategyDefs.h"

#include "../Share/StdUtils.hpp"
#include "../Share/DLLHelper.hpp"
#include "../Share/fmtlib.h"

class HisDataReplayer;

/*!
 * \class HftMocker
 * \brief HFT策略模拟器类
 * 
 * \details 该类实现了IHftStraCtx（HFT策略上下文接口）和IDataSink（数据接收接口），
 *          为HFT策略在回测环境下提供完整的运行上下文。主要功能包括：
 *          - 策略生命周期管理（初始化、运行、结束）
 *          - 高频交易接口实现（买入、卖出、撤单）
 *          - 持仓管理和资金管理
 *          - Level2数据处理（订单队列、订单明细、成交明细）
 *          - 历史数据访问
 *          - 交易信号记录和统计
 *          - 策略日志输出
 * 
 * \note 该类是回测系统的核心组件，提供与实盘环境一致的HFT策略接口
 */
class HftMocker : public IDataSink, public IHftStraCtx
{
public:
	/*!
	 * \brief 构造函数
	 * \details 创建HFT模拟器实例，初始化各项参数
	 * 
	 * \param replayer 历史数据回放器指针
	 * \param name 策略名称
	 */
	HftMocker(HisDataReplayer* replayer, const char* name);
	
	/*!
	 * \brief 析构函数
	 * \details 清理资源，导出回测结果
	 */
	virtual ~HftMocker();

private:
	/*!
	 * \brief 格式化调试日志输出
	 * \details 使用格式化字符串输出调试级别日志
	 */
	template<typename... Args>
	void log_debug(const char* format, const Args& ...args)
	{
		std::string s = fmt::sprintf(format, args...);
		stra_log_debug(s.c_str());
	}

	/*!
	 * \brief 格式化信息日志输出
	 * \details 使用格式化字符串输出信息级别日志
	 */
	template<typename... Args>
	void log_info(const char* format, const Args& ...args)
	{
		std::string s = fmt::sprintf(format, args...);
		stra_log_info(s.c_str());
	}

	/*!
	 * \brief 格式化错误日志输出
	 * \details 使用格式化字符串输出错误级别日志
	 */
	template<typename... Args>
	void log_error(const char* format, const Args& ...args)
	{
		std::string s = fmt::sprintf(format, args...);
		stra_log_error(s.c_str());
	}

public:
	//////////////////////////////////////////////////////////////////////////
	//IDataSink接口实现 - 数据接收处理
	
	/*! \brief 处理Tick数据 */
	virtual void	handle_tick(const char* stdCode, WTSTickData* curTick) override;
	/*! \brief 处理委托队列数据 */
	virtual void	handle_order_queue(const char* stdCode, WTSOrdQueData* curOrdQue) override;
	/*! \brief 处理委托明细数据 */
	virtual void	handle_order_detail(const char* stdCode, WTSOrdDtlData* curOrdDtl) override;
	/*! \brief 处理成交明细数据 */
	virtual void	handle_transaction(const char* stdCode, WTSTransData* curTrans) override;

	/*! \brief 处理K线收盘事件 */
	virtual void	handle_bar_close(const char* stdCode, const char* period, uint32_t times, WTSBarStruct* newBar) override;
	/*! \brief 处理定时调度事件 */
	virtual void	handle_schedule(uint32_t uDate, uint32_t uTime) override;

	/*! \brief 处理初始化事件 */
	virtual void	handle_init() override;
	/*! \brief 处理交易时段开始事件 */
	virtual void	handle_session_begin(uint32_t curTDate) override;
	/*! \brief 处理交易时段结束事件 */
	virtual void	handle_session_end(uint32_t curTDate) override;

	/*! \brief 处理回测完成事件 */
	virtual void	handle_replay_done() override;

	/*! \brief Tick数据更新通知 */
	virtual void	on_tick_updated(const char* stdCode, WTSTickData* newTick) override;
	/*! \brief 委托队列数据更新通知 */
	virtual void	on_ordque_updated(const char* stdCode, WTSOrdQueData* newOrdQue) override;
	/*! \brief 委托明细数据更新通知 */
	virtual void	on_orddtl_updated(const char* stdCode, WTSOrdDtlData* newOrdDtl) override;
	/*! \brief 成交明细数据更新通知 */
	virtual void	on_trans_updated(const char* stdCode, WTSTransData* newTrans) override;

	//////////////////////////////////////////////////////////////////////////
	//IHftStraCtx接口实现 - HFT策略上下文接口
	
	/*! \brief 策略Tick数据回调 */
	virtual void on_tick(const char* stdCode, WTSTickData* newTick) override;

	/*! \brief 策略委托队列数据回调 */
	virtual void on_order_queue(const char* stdCode, WTSOrdQueData* newOrdQue) override;

	/*! \brief 策略委托明细数据回调 */
	virtual void on_order_detail(const char* stdCode, WTSOrdDtlData* newOrdDtl) override;

	/*! \brief 策略成交明细数据回调 */
	virtual void on_transaction(const char* stdCode, WTSTransData* newTrans) override;

	/*! \brief 获取策略ID */
	virtual uint32_t id() override;

	/*! \brief 策略初始化回调 */
	virtual void on_init() override;

	/*! \brief 策略K线数据回调 */
	virtual void on_bar(const char* stdCode, const char* period, uint32_t times, WTSBarStruct* newBar) override;

	/*! \brief 策略交易时段开始回调 */
	virtual void on_session_begin(uint32_t curTDate) override;

	/*! \brief 策略交易时段结束回调 */
	virtual void on_session_end(uint32_t curTDate) override;

	/*!
	 * \brief 撤销指定订单
	 * \param localid 本地订单ID
	 * \return 是否撤销成功
	 */
	virtual bool stra_cancel(uint32_t localid) override;

	/*!
	 * \brief 撤销指定合约的指定方向订单
	 * \param stdCode 标准合约代码
	 * \param isBuy 是否买入方向
	 * \param qty 撤销数量，0表示全部撤销
	 * \return 被撤销的订单ID列表
	 */
	virtual OrderIDs stra_cancel(const char* stdCode, bool isBuy, double qty = 0) override;

	/*!
	 * \brief 买入下单
	 * \param stdCode 标准合约代码
	 * \param price 委托价格
	 * \param qty 下单数量
	 * \param userTag 用户标签
	 * \param flag 下单标志: 0-normal，1-fak，2-fok，默认0
	 * \return 订单ID列表
	 */
	virtual OrderIDs stra_buy(const char* stdCode, double price, double qty, const char* userTag, int flag = 0) override;

	/*!
	 * \brief 卖出下单
	 * \param stdCode 标准合约代码
	 * \param price 委托价格
	 * \param qty 下单数量
	 * \param userTag 用户标签
	 * \param flag 下单标志: 0-normal，1-fak，2-fok，默认0
	 * \return 订单ID列表
	 */
	virtual OrderIDs stra_sell(const char* stdCode, double price, double qty, const char* userTag, int flag = 0) override;

	/*! \brief 获取品种信息 */
	virtual WTSCommodityInfo* stra_get_comminfo(const char* stdCode) override;

	/*! \brief 获取K线数据 */
	virtual WTSKlineSlice* stra_get_bars(const char* stdCode, const char* period, uint32_t count) override;

	/*! \brief 获取Tick数据 */
	virtual WTSTickSlice* stra_get_ticks(const char* stdCode, uint32_t count) override;

	/*! \brief 获取委托明细数据 */
	virtual WTSOrdDtlSlice*	stra_get_order_detail(const char* stdCode, uint32_t count) override;

	/*! \brief 获取委托队列数据 */
	virtual WTSOrdQueSlice*	stra_get_order_queue(const char* stdCode, uint32_t count) override;

	/*! \brief 获取成交明细数据 */
	virtual WTSTransSlice*	stra_get_transaction(const char* stdCode, uint32_t count) override;

	/*! \brief 获取最新Tick数据 */
	virtual WTSTickData* stra_get_last_tick(const char* stdCode) override;

	/*!
	 * \brief 获取持仓
	 * \param stdCode 标准合约代码
	 * \param bOnlyValid 只获取可用持仓
	 * \return 持仓数量
	 */
	virtual double stra_get_position(const char* stdCode, bool bOnlyValid = false) override;

	/*! \brief 获取持仓盈亏 */
	virtual double stra_get_position_profit(const char* stdCode) override;

	/*! \brief 获取未完成订单数量 */
	virtual double stra_get_undone(const char* stdCode) override;

	/*! \brief 获取最新价格 */
	virtual double stra_get_price(const char* stdCode) override;

	/*! \brief 获取当前日期 */
	virtual uint32_t stra_get_date() override;

	/*! \brief 获取当前时间 */
	virtual uint32_t stra_get_time() override;

	/*! \brief 获取当前秒数 */
	virtual uint32_t stra_get_secs() override;

	/*! \brief 订阅Tick数据 */
	virtual void stra_sub_ticks(const char* stdCode) override;

	/*! \brief 订阅委托队列数据 */
	virtual void stra_sub_order_queues(const char* stdCode) override;

	/*! \brief 订阅委托明细数据 */
	virtual void stra_sub_order_details(const char* stdCode) override;

	/*! \brief 订阅成交明细数据 */
	virtual void stra_sub_transactions(const char* stdCode) override;

	/*! \brief 输出信息日志 */
	virtual void stra_log_info(const char* message) override;
	/*! \brief 输出调试日志 */
	virtual void stra_log_debug(const char* message) override;
	/*! \brief 输出错误日志 */
	virtual void stra_log_error(const char* message) override;

	/*! \brief 保存用户数据 */
	virtual void stra_save_user_data(const char* key, const char* val) override;

	/*! \brief 加载用户数据 */
	virtual const char* stra_load_user_data(const char* key, const char* defVal = "") override;

	//////////////////////////////////////////////////////////////////////////
	/*!
	 * \brief 成交回报回调
	 * \param localid 本地订单ID
	 * \param stdCode 标准合约代码
	 * \param isBuy 是否买入
	 * \param vol 成交数量
	 * \param price 成交价格
	 * \param userTag 用户标签
	 */
	virtual void on_trade(uint32_t localid, const char* stdCode, bool isBuy, double vol, double price, const char* userTag);

	/*!
	 * \brief 订单回报回调
	 * \param localid 本地订单ID
	 * \param stdCode 标准合约代码
	 * \param isBuy 是否买入
	 * \param totalQty 订单总数量
	 * \param leftQty 剩余数量
	 * \param price 订单价格
	 * \param isCanceled 是否已撤销
	 * \param userTag 用户标签
	 */
	virtual void on_order(uint32_t localid, const char* stdCode, bool isBuy, double totalQty, double leftQty, double price, bool isCanceled, const char* userTag);

	/*!
	 * \brief 交易通道就绪回调
	 */
	virtual void on_channel_ready();

	/*!
	 * \brief 委托确认回调
	 * \param localid 本地订单ID
	 * \param stdCode 标准合约代码
	 * \param bSuccess 是否成功
	 * \param message 返回消息
	 * \param userTag 用户标签
	 */
	virtual void on_entrust(uint32_t localid, const char* stdCode, bool bSuccess, const char* message, const char* userTag);

public:
	/*!
	 * \brief 初始化HFT策略工厂
	 * \param cfg 配置参数
	 * \return 是否初始化成功
	 */
	bool	init_hft_factory(WTSVariant* cfg);
	
	/*!
	 * \brief 安装钩子
	 */
	void	install_hook();
	
	/*!
	 * \brief 启用钩子
	 * \param bEnabled 是否启用，默认true
	 */
	void	enable_hook(bool bEnabled = true);
	
	/*!
	 * \brief 步进Tick处理
	 */
	void	step_tick();

private:
	typedef std::function<void()> Task;		/*!< 任务函数类型定义 */
	
	/*!
	 * \brief 提交任务到任务队列
	 * \param task 要执行的任务
	 */
	void	postTask(Task task);
	
	/*!
	 * \brief 处理任务队列中的任务
	 */
	void	procTask();

	/*!
	 * \brief 处理订单
	 * \param localid 本地订单ID
	 * \return 是否处理成功
	 */
	bool	procOrder(uint32_t localid);

	/*!
	 * \brief 设置持仓
	 * \param stdCode 标准合约代码
	 * \param qty 持仓数量
	 * \param price 价格
	 * \param userTag 用户标签
	 */
	void	do_set_position(const char* stdCode, double qty, double price = 0.0, const char* userTag = "");
	
	/*!
	 * \brief 更新动态盈亏
	 * \param stdCode 标准合约代码
	 * \param newTick 最新Tick数据
	 */
	void	update_dyn_profit(const char* stdCode, WTSTickData* newTick);

	/*!
	 * \brief 导出输出结果
	 */
	void	dump_outputs();
	
	/*!
	 * \brief 记录交易日志
	 * \param stdCode 标准合约代码
	 * \param isLong 是否多头
	 * \param isOpen 是否开仓
	 * \param curTime 当前时间
	 * \param price 成交价格
	 * \param qty 成交数量
	 * \param fee 手续费
	 * \param userTag 用户标签
	 */
	inline void	log_trade(const char* stdCode, bool isLong, bool isOpen, uint64_t curTime, double price, double qty, double fee, const char* userTag);
	
	/*!
	 * \brief 记录平仓日志
	 * \param stdCode 标准合约代码
	 * \param isLong 是否多头
	 * \param openTime 开仓时间
	 * \param openpx 开仓价格
	 * \param closeTime 平仓时间
	 * \param closepx 平仓价格
	 * \param qty 平仓数量
	 * \param profit 本次盈亏
	 * \param maxprofit 最大浮盈
	 * \param maxloss 最大浮亏
	 * \param totalprofit 累计盈亏
	 * \param enterTag 开仓标签
	 * \param exitTag 平仓标签
	 */
	inline void	log_close(const char* stdCode, bool isLong, uint64_t openTime, double openpx, uint64_t closeTime, double closepx, double qty,
		double profit, double maxprofit, double maxloss, double totalprofit, const char* enterTag, const char* exitTag);

private:
	HisDataReplayer*	_replayer;			/*!< 历史数据回放器指针 */

	bool			_use_newpx;				/*!< 是否使用最新价格 */
	uint32_t		_error_rate;			/*!< 错误率设置 */

	typedef faster_hashmap<std::string, double> PriceMap;
	PriceMap		_price_map;				/*!< 价格映射表，存储最新价格 */

	/*!
	 * \struct _StraFactInfo
	 * \brief 策略工厂信息结构
	 * 
	 * 管理HFT策略工厂的动态库加载、实例创建和销毁等
	 */
	typedef struct _StraFactInfo
	{
		std::string		_module_path;		/*!< 模块路径 */
		DllHandle		_module_inst;		/*!< 动态库句柄 */
		IHftStrategyFact*	_fact;			/*!< 策略工厂指针 */
		FuncCreateHftStraFact	_creator;	/*!< 工厂创建函数 */
		FuncDeleteHftStraFact	_remover;	/*!< 工厂删除函数 */

		_StraFactInfo()
		{
			_module_inst = NULL;
			_fact = NULL;
		}

		~_StraFactInfo()
		{
			if (_fact)
				_remover(_fact);
		}
	} StraFactInfo;
	StraFactInfo	_factory;				/*!< 策略工厂信息 */

	HftStrategy*	_strategy;				/*!< HFT策略实例指针 */

	StdThreadPtr		_thrd;				/*!< 工作线程指针 */
	StdUniqueMutex		_mtx;				/*!< 任务队列互斥锁 */
	std::queue<Task>	_tasks;				/*!< 任务队列 */
	bool				_stopped;			/*!< 是否停止标志 */

	StdRecurMutex		_mtx_control;		/*!< 控制操作互斥锁 */

	/*!
	 * \struct _OrderInfo
	 * \brief 订单信息结构
	 * 
	 * 记录单个订单的详细信息，包括方向、价格、数量、用户标签等
	 */
	typedef struct _OrderInfo
	{
		bool	_isBuy;						/*!< 是否买入订单 */
		char	_code[32];					/*!< 合约代码 */
		double	_price;						/*!< 委托价格 */
		double	_total;						/*!< 委托总量 */
		double	_left;						/*!< 剩余数量 */
		char	_usertag[32];				/*!< 用户标签 */
		
		uint32_t	_localid;				/*!< 本地订单ID */

		_OrderInfo()
		{
			memset(this, 0, sizeof(_OrderInfo));
		}

	} OrderInfo;
	typedef faster_hashmap<uint32_t, OrderInfo> Orders;
	StdRecurMutex	_mtx_ords;				/*!< 订单操作互斥锁 */
	Orders			_orders;				/*!< 订单映射表 */

	typedef WTSHashMap<std::string> CommodityMap;
	CommodityMap*	_commodities;			/*!< 品种映射表 */

	//用户数据
	typedef faster_hashmap<std::string, std::string> StringHashMap;
	StringHashMap	_user_datas;			/*!< 用户自定义数据 */
	bool			_ud_modified;			/*!< 用户数据是否修改 */

	/*!
	 * \struct _DetailInfo
	 * \brief 持仓明细信息结构
	 * 
	 * 记录单笔开仓的详细信息，用于计算盈亏和风险管理
	 */
	typedef struct _DetailInfo
	{
		bool		_long;					/*!< 是否多头 */
		double		_price;					/*!< 开仓价格 */
		double		_volume;				/*!< 开仓数量 */
		uint64_t	_opentime;				/*!< 开仓时间戳 */
		uint32_t	_opentdate;				/*!< 开仓交易日 */
		double		_max_profit;			/*!< 最大浮盈 */
		double		_max_loss;				/*!< 最大浮亏 */
		double		_profit;				/*!< 当前盈亏 */
		char		_usertag[32];			/*!< 用户标签 */

		_DetailInfo()
		{
			memset(this, 0, sizeof(_DetailInfo));
		}
	} DetailInfo;

	/*!
	 * \struct _PosInfo
	 * \brief 持仓信息结构
	 * 
	 * 记录单个合约的持仓信息，包含多空净持仓和明细
	 */
	typedef struct _PosInfo
	{
		double		_volume;				/*!< 净持仓数量（正为多头，负为空头） */
		double		_closeprofit;			/*!< 已实现盈亏 */
		double		_dynprofit;				/*!< 浮动盈亏 */
		double		_frozen;				/*!< 冻结数量 */

		std::vector<DetailInfo> _details;	/*!< 持仓明细列表 */

		_PosInfo()
		{
			_volume = 0;
			_closeprofit = 0;
			_dynprofit = 0;
			_frozen = 0;
		}

		inline double valid() const { return _volume - _frozen; }	/*!< 获取可用持仓 */
	} PosInfo;
	typedef faster_hashmap<std::string, PosInfo> PositionMap;
	PositionMap		_pos_map;				/*!< 持仓映射表 */

	std::stringstream	_trade_logs;		/*!< 交易日志流 */
	std::stringstream	_close_logs;		/*!< 平仓日志流 */
	std::stringstream	_fund_logs;			/*!< 资金日志流 */
	std::stringstream	_sig_logs;			/*!< 信号日志流 */

	/*!
	 * \struct _StraFundInfo
	 * \brief 策略资金信息结构
	 * 
	 * 记录策略的资金状态，包括总盈亏、动态盈亏和手续费等
	 */
	typedef struct _StraFundInfo
	{
		double	_total_profit;				/*!< 总盈亏 */
		double	_total_dynprofit;			/*!< 总浮动盈亏 */
		double	_total_fees;				/*!< 总手续费 */

		_StraFundInfo()
		{
			memset(this, 0, sizeof(_StraFundInfo));
		}
	} StraFundInfo;

	StraFundInfo		_fund_info;			/*!< 策略资金信息 */

protected:
	uint32_t		_context_id;			/*!< 策略上下文ID */

	StdUniqueMutex	_mtx_calc;				/*!< 计算互斥锁 */
	StdCondVariable	_cond_calc;				/*!< 计算条件变量 */
	bool			_has_hook;				/*!< 是否安装了钩子 */
	bool			_hook_valid;			/*!< 钩子是否有效（用于异步回调模式下确保计算的有效性） */
	std::atomic<bool>	_resumed;			/*!< 是否暂停（用于控制状态） */

	//tick订阅列表
	faster_hashset<std::string> _tick_subs;	/*!< Tick数据订阅合约列表 */
};

